/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package configuration;

import autoUpdate.WatchEntry;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import platforms.PlatformSupport;

/**
 *
 * @author zalem1
 */
public class ConfigurationManager {
    private static String DEFAULT_CONFIGURATION_PATH = "configuration.xml";
    
    private static Preferences _configuration = null;
    private static UpdateDatabase _updateDatabase;
    
    public static void LoadConfiguration()
    {
        LoadPreferences(DEFAULT_CONFIGURATION_PATH);

        String updateDatabasePath = _configuration.getUpdateDatabasePath();
        LoadUpdateDatabase(updateDatabasePath);
    }
    
    
    public static void SaveConfiguration()
    {
        SavePreferences(DEFAULT_CONFIGURATION_PATH);

        String updateDatabasePath = _configuration.getUpdateDatabasePath();
        SaveUpdateDatabase(updateDatabasePath);
    }
    
        
    public static Preferences GetPreferences()
    {
        if (_configuration == null)
            LoadConfiguration();
        
        return _configuration;
    }    
    
    private static void ValidatePreferences()
    {
        if (_configuration.getUserAccounts() == null)
            _configuration.setUserAccounts(new ArrayList<PicasaAccount>());

        if (_configuration.getUpdateDatabasePath() == null)
            _configuration.setUpdateDatabasePath(Defaults.UpdateDatabasePath);

        if (_configuration.getPreviewPictureCount() > Defaults.MaxPreviewPictures || _configuration.getPreviewPictureCount() < Defaults.MinPreviewPictures)
        {
            _configuration.setPreviewPictureCount(9);
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "Preview Picture Count has to be between a number between {0} and {1}", new Object[]{Defaults.MinPreviewPictures, Defaults.MaxPreviewPictures});
        }

        if (_configuration.getPoolingInterval() > Defaults.MaxPoolingInterval || _configuration.getPoolingInterval() < Defaults.MinPoolingInterval)
        {
            _configuration.setPoolingInterval(Defaults.MinPoolingInterval);
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "Pooling interval has to be between a number between {0} and {1}", new Object[]{Defaults.MinPoolingInterval, Defaults.MaxPoolingInterval});
        }
        
        String sysTrayIconPath = _configuration.getSystemTryIconPath();
        if (sysTrayIconPath == null || sysTrayIconPath.equals(""))
        {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "System tray icon path is empty, reverting to the default icon path.", sysTrayIconPath);
            _configuration.setSystemTryIconPath(null);
        } else if (!(new File(sysTrayIconPath).exists()))
        {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "System tray icon {0} doesn't exist, reverting to the default icon path.", sysTrayIconPath);
            _configuration.setSystemTryIconPath(null);
        }
        
        if (_configuration.getAutoSyncNewAlbums() == null) {
            _configuration.setAutoSyncNewAlbums(true);
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "Setting auto sync new albums to the default value - true");
        }
            
        if (_configuration.getDownloadPhotos() == null) {
            _configuration.setDownloadPhotos(true);
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "Setting download photos to the default value - true");
        }
            
        if (_configuration.getDownloadVideos() == null) {
            _configuration.setDownloadVideos(false);
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "Setting download videos to the default value - false");
        }
            
        if (_configuration.getDefaultPhotoFolder() == null || _configuration.getDefaultPhotoFolder().isEmpty()) {
            _configuration.setDefaultPhotoFolder(getDefaultPhotoFolder());
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "Setting default photo download folder to the default {0}", getDefaultPhotoFolder());
        } else if (!(new File(_configuration.getDefaultPhotoFolder()).exists())) {
            _configuration.setDefaultPhotoFolder(getDefaultPhotoFolder());
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "Download folder {0} doesn''t exists. Setting default photo download folder to the default {1}", new Object[]{_configuration.getDefaultPhotoFolder(), getDefaultPhotoFolder()});
        }
        
        if (_configuration.getDefaultResolution() == null) {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "Default picture download resolution is not set. Setting it to the default value {0}", _configuration.getDefaultResolution());
            _configuration.setDefaultResolution(Defaults.DefaultResolution.toString());
        }
        if (_configuration.getSmallResolution() == null) {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "Default small resolution is not set. Setting it to the default value {0}", _configuration.getSmallResolution());
            _configuration.setSmallResolution(Defaults.SmallResolution.toString());
        }
        if (_configuration.getMediumResolution() == null) {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "Default medium resolution is not set. Setting it to the default value {0}", _configuration.getMediumResolution());
            _configuration.setMediumResolution(Defaults.MediumResolution.toString());
        }
        if (_configuration.getLargeResolution() == null) {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.WARNING, "Default large resolution is not set. Setting it to the default value {0}", _configuration.getLargeResolution());
            _configuration.setLargeResolution(Defaults.LargeResolution.toString());
        }
    }

    private static String getDefaultPhotoFolder() {
        switch (PlatformSupport.getPlatformName()) {
            case WINDOWS:
                return Defaults.WindowsPhotoFolder;
            case MAC:
                return Defaults.MacPhotoFolder;
            case LINUX:
                return Defaults.LinuxPhotoFolder;
            default:
                return Defaults.PhotoFolder;
        }

    }


    private static void LoadPreferences(String preferenceFilePath) {
        FileInputStream inputStream;
        try {
            inputStream = new FileInputStream(preferenceFilePath);
            XMLDecoder decoder = new XMLDecoder(inputStream);
            _configuration = (Preferences)decoder.readObject();
            decoder.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.SEVERE, "Cannot find preferences file", ex);
            _configuration = new Preferences();
        } catch (Exception ex) {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.SEVERE, "Cannot load preferences", ex);
            _configuration = new Preferences();

        }

        ValidatePreferences();
    }

    private static void SavePreferences(String preferenceFilePath) {
        File configurationFile = new File(preferenceFilePath);

        if (!configurationFile.exists())
            try {
                configurationFile.createNewFile();
            } catch (IOException ex) {
                Logger.getLogger(ConfigurationManager.class.getName()).log(Level.SEVERE, "Cannot create preferences file", ex);
                return;
            }

        try {
            FileOutputStream outputStream = new FileOutputStream(preferenceFilePath);
            XMLEncoder encoder = new XMLEncoder(outputStream);
            encoder.writeObject(_configuration);
            encoder.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.SEVERE, "Cannot save preferences", ex);
        }
    }



    private static void LoadUpdateDatabase(String updateDatabasePath) {
        FileInputStream inputStream;
        try {
            inputStream = new FileInputStream(updateDatabasePath);
            XMLDecoder decoder = new XMLDecoder(inputStream);
            _updateDatabase = ((UpdateDatabase) decoder.readObject());
            decoder.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.SEVERE, "Cannot find updateDatabase file", ex);
            _updateDatabase = new UpdateDatabase();
        } catch (Exception ex) {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.SEVERE, "Cannot load updateDatabase", ex);
            _configuration = new Preferences();

        }


        ValidateUpdateDatabase();
    }

    private static void SaveUpdateDatabase(String updateDatabasePath) {
        File updateDatabaseFile = new File(updateDatabasePath);

        if (!updateDatabaseFile.exists())
            try {
                updateDatabaseFile.createNewFile();
            } catch (IOException ex) {
                Logger.getLogger(ConfigurationManager.class.getName()).log(Level.SEVERE, "cannot create update database file", ex);
                return;
            }

        try {
            FileOutputStream outputStream = new FileOutputStream(updateDatabasePath);
            XMLEncoder encoder = new XMLEncoder(outputStream);
            encoder.writeObject(_updateDatabase);
            encoder.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.SEVERE, "Cannot save update database file as the file doesn't exist", ex);
        } catch (Exception ex) {
            Logger.getLogger(ConfigurationManager.class.getName()).log(Level.SEVERE, "Cannot save updateDatabase file", ex);
            _configuration = new Preferences();

        }

    }

    private static void ValidateUpdateDatabase() {
        if (getUpdateDatabase().getWatchedAlbums() == null)
            getUpdateDatabase().setWatchedAlbums(new HashMap<String, WatchEntry>());
    }

    /**
     * @return the _updateDatabase
     */
    public static UpdateDatabase getUpdateDatabase() {
        if (_updateDatabase == null)
            _updateDatabase = new UpdateDatabase();

        return _updateDatabase;
    }

                
        
}
